package org.dolphin.action.security;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ExceptionMapping;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.InterceptorRefs;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.dolphin.base.bean.LocaleVO;
import org.dolphin.base.bean.UserVO;
import org.dolphin.base.constant.Status;
import org.dolphin.base.json.PaginationBean;
import org.dolphin.base.json.StatusBean;
import org.dolphin.entity.misc.UserLocale;
import org.dolphin.entity.security.User;
import org.dolphin.service.SecurityControlService;
import org.dolphin.service.misc.LocaleService;
import org.dolphin.util.ExceptionHelper;
import org.dolphin.util.Pagination;
import org.hibernate.criterion.Order;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import com.opensymphony.xwork2.ActionSupport;

@ParentPackage(value = "custom-default")
@Namespace(value = "/security")
@InterceptorRefs(value = {@InterceptorRef(value = "customStack")})
public class UserAction extends ActionSupport {
  private static final long serialVersionUID = 7250527627624625179L;
  private Long id;
  private Integer page;
  private Integer rows;
  private String sidx;
  private String sord;
  private SecurityControlService securityControlService;
  private LocaleService localeService;
  private PaginationBean pagination;
  private List<LocaleVO> locales;
  private String username;
  private String firstname;
  private String lastname;
  private String address;
  private String password;
  private Long userLocale;
  private Long version;
  private StatusBean status;

  @Action(value = "createUser", results = @Result(name = "success", params = {"root", "status"}, type = "json"), exceptionMappings = @ExceptionMapping(exception = "java.lang.Exception", result = "success", params = {
      "param", "param1"}))
  public String createUser() {
    UserLocale locale = getLocaleService().loadLocaleById(getUserLocale());
    User user = new User();
    user.setUsername(getUsername());
    user.setFirstname(getFirstname());
    user.setLastname(getLastname());
    user.setAddress(getAddress());
    user.setPassword(getPassword());
    user.setUserLocale(locale);
    status = new StatusBean();
    boolean error = false;
    String msg = "";
    try {
      getSecurityControlService().createUser(user);
    } catch (Exception e) {
      error = true;
      Throwable ex = ExceptionHelper.getRootCause(e);
      msg = ex.getMessage();
    } finally {
      status.setStatus(error ? Status.ERROR : Status.SUCCESS);
      if (error && msg != null) {
        status.addError(msg);
      }
    }
    return SUCCESS;
  }

  public String getAddress() {
    return address;
  }

  public String getFirstname() {
    return firstname;
  }

  public Long getId() {
    return id;
  }

  public String getLastname() {
    return lastname;
  }

  public List<LocaleVO> getLocales() {
    return locales;
  }

  public LocaleService getLocaleService() {
    return localeService;
  }

  public Integer getPage() {
    return page;
  }

  public PaginationBean getPagination() {
    return pagination;
  }

  public String getPassword() {
    return password;
  }

  public Integer getRows() {
    return rows;
  }

  public SecurityControlService getSecurityControlService() {
    return securityControlService;
  }

  public String getSidx() {
    return sidx;
  }

  public String getSord() {
    return sord;
  }

  public StatusBean getStatus() {
    return status;
  }

  public Long getUserLocale() {
    return userLocale;
  }

  @Action(value = "getUserLocales", results = @Result(name = "success", params = {"root",
      "pagination.rows"}, type = "json"))
  public String getUserLocales() {
    locales = getLocaleService().getLocales();
    pagination = new PaginationBean();
    pagination.setRows(locales);
    return SUCCESS;
  }

  public String getUsername() {
    return username;
  }

  @Action(value = "getUsers", results = @Result(name = "success", params = {"root", "pagination"}, type = "json"))
  public String getUsers() {
    List<Order> orders = null;
    if (StringUtils.hasText(getSidx())) {
      orders = new ArrayList<Order>(1);
      Order order = ObjectUtils.nullSafeEquals("desc", getSord()) ? Order.desc(getSidx()) : Order
          .asc(getSidx());
      orders.add(order);
    }
    List<UserVO> results = getSecurityControlService().getUsers(getPage(), getRows(), orders);
    Long records = getSecurityControlService().getUsersCount();
    Integer total = Pagination.calculateTotalPage(records, getRows());
    pagination = new PaginationBean();
    pagination.setPage(getPage());
    pagination.setRecords(records);
    pagination.setTotal(total);
    pagination.setRows(results);
    return SUCCESS;
  }

  public Long getVersion() {
    return version;
  }

  @Action(value = "listUser", results = @Result(name = "success", location = "listUser.jsp"))
  public String list() throws IOException {
    return SUCCESS;
  }

  public void setAddress(String address) {
    this.address = address;
  }

  public void setFirstname(String firstname) {
    this.firstname = firstname;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public void setLastname(String lastname) {
    this.lastname = lastname;
  }

  public void setLocales(List<LocaleVO> userLocales) {
    this.locales = userLocales;
  }

  public void setLocaleService(LocaleService localeService) {
    this.localeService = localeService;
  }

  public void setPage(Integer page) {
    this.page = page;
  }

  public void setPagination(PaginationBean pagination) {
    this.pagination = pagination;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public void setRows(Integer rows) {
    this.rows = rows;
  }

  public void setSecurityControlService(SecurityControlService securityControlService) {
    this.securityControlService = securityControlService;
  }

  public void setSidx(String sidx) {
    this.sidx = sidx;
  }

  public void setSord(String sord) {
    this.sord = sord;
  }

  public void setStatus(StatusBean status) {
    this.status = status;
  }

  public void setUserLocale(Long userLocale) {
    this.userLocale = userLocale;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public void setVersion(Long version) {
    this.version = version;
  }

  @Action(value = "updateUser", results = @Result(name = "success", params = {"root", "status"}, type = "json"))
  public String updateUser() {
    status = new StatusBean();
    User user = getSecurityControlService().fetchUser(getId());
    user.setVersion(getVersion());
    user.setAddress(getAddress());
    boolean error = false;
    String msg = "";
    try {
      getSecurityControlService().updateUser(user);
    } catch (Exception e) {
      error = true;
      Throwable ex = ExceptionHelper.getRootCause(e);
      msg = ex.getMessage();
    } finally {
      status.setStatus(error ? Status.ERROR : Status.SUCCESS);
      if (error) {
        if (msg != null) {
          status.addError(msg);
        }
      } else {
        status.addAttr("version", user.getVersion());
      }
    }
    return SUCCESS;
  }
}
